#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <math.h>

typedef struct
{
  byte val;
  byte last_val;
}KEY_T;
KEY_T key[2] = {0};

typedef struct
{
  byte id;
  byte press;
  byte update_flag;
  byte res;
}KEY_MSG;
KEY_MSG key_msg = {0};

typedef struct
{
  char* str;
  byte len;
}SETTING_LIST;

SETTING_LIST list[] = 
{
  {"list",4},
  {"ab",2},
  {"abc",3},
};

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

short x,x_trg; //x当前位置数值,x_trg 目标坐标值
short y = 18,y_trg = 18;

short frame_len,frame_len_trg;//框框的宽度
short frame_y,frame_y_trg;//框框的y

 char ui_select = 0;  // signed char 的范围：-128-127；unsigned char 的范围：0-255

byte get_io_val(byte ch); // 按键状态读取
void key_init(void);
void key_scan(void);  // 按键扫描

int ui_run(short *a,short *a_trg,byte step,byte slow_cnt); // 目标位置控制
void ui_proc(void); // 运动过程控制
void ui_show(void);

byte get_io_val(byte ch)
{
  if(ch == 0)
  {
    return digitalRead(2);
  }
  else
  {
    return digitalRead(3);
  }
}

void key_init(void)
{
  for(int i = 0;i<2;i++)
  {
    key[i].val = key[i].last_val = get_io_val(i);
  }
}

void key_scan(void)
{
  for(int i = 0;i<2;i++)
  {
    key[i].val =  get_io_val(i);
    if(key[i].val != key[i].last_val)
    {
      key[i].last_val = key[i].val;
      if(key[i].val == 0)
      {
        key_msg.id = i;
        key_msg.press = 1;
        key_msg.update_flag = 1;
      }
    }
  }
}

/*
a：当前位置
a_trg：目标位置
step：速度1，加速到达目标值
slow_cnt：速度2：减小震荡
*/
int ui_run(short *a,short *a_trg,byte step,byte slow_cnt)
{  
  byte temp;

  temp = abs(*a_trg-*a) > slow_cnt ? step : 1;  // 速度控制
  if(*a < *a_trg)
  {
    *a += temp;
  }
  else if( *a > *a_trg)
  {
    *a -= temp;  
  }
  else
  {
    return 0;
  }
  return 1;
}

void setup(void) 
{
 	pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  key_init();
  u8g2.begin();
  u8g2.setFont(u8g2_font_t0_22_mf ); //设置字体
  frame_len = frame_len_trg = list[ui_select].len*13;
}

void loop(void) 
{
  key_scan();
  ui_proc();  
}

void ui_show(void)
{
  int list_len = sizeof(list) / sizeof(SETTING_LIST);
  u8g2.clearBuffer();       
  for(int i = 0 ;i < list_len;i++)
  {
    u8g2.drawStr(x+2,y+i*20,list[i].str);  
  }
  u8g2.drawRFrame(x,frame_y,frame_len,22,3);
  ui_run(&frame_y,&frame_y_trg,5,4);
  ui_run(&frame_len,&frame_len_trg,10,5);
  u8g2.sendBuffer();          
}

void ui_proc(void)
{
  int list_len = sizeof(list) / sizeof(SETTING_LIST);

  if(key_msg.update_flag && key_msg.press)
  {
    key_msg.update_flag = 0;
    if(key_msg.id)
    {
     ui_select++;
     if(ui_select >= list_len)
     {
        ui_select = list_len-1 ;  
     }
    }
    else
    {
      ui_select--;
      if(ui_select < 0)
      {
        ui_select = 0;  
      }
    }
    frame_y_trg = ui_select*20; // 根据字符的高度计算目标位置
    frame_len_trg = list[ui_select].len*13;
  }
  ui_show();
}